﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using ShopSpace.Core;
using ShopSpace.Core.Repositories;
using DotNetNuke.Entities.Modules;
using DotNetNuke.UI.Skins;
using ShopSpace.Infrastructure.UI;
using NHibernate.Criterion;

namespace ShopSpace.UI.DotNetNukeModules
{
	public partial class ViewWorkItems : ModuleControlBase
	{
		protected void Page_Load(object sender, EventArgs e)
		{
			try
			{
				if (!Page.IsPostBack)
				{
					if (this.Person != null)
					{
						this.BindProjects();
						Project project = this.GetSelectedProject();
						this.BindGrid(project);
						this.SetupLinks(project);
					}
					else
					{
						Skin.AddModuleMessage(this, "No Person associated with your account", DotNetNuke.UI.Skins.Controls.ModuleMessage.ModuleMessageType.YellowWarning);
						this.pnlMain.Visible = false;
					}
				}
			}
			catch (Exception ex)
			{
				this.HandleException(ex);
			}
		}

		protected void ddlProject_SelectedIndexChanged(object sender, EventArgs e)
		{
			try
			{
				Project project = this.GetSelectedProject();
				this.SaveToUserState(project);
				this.SetupLinks(project);
				this.BindGrid(project);
			}
			catch (Exception ex)
			{
				this.HandleException(ex);
			}
		}

		protected void chkOpenOnly_CheckedChanged(object sender, EventArgs e)
		{
			try
			{
				this.BindGrid(this.GetSelectedProject());
			}
			catch (Exception ex)
			{
				this.HandleException(ex);
			}
		}

		protected void gvWorkItems_RowDataBound(object sender, GridViewRowEventArgs e)
		{
			if ( e.Row.RowType == DataControlRowType.DataRow )
			{
				WorkItem workItem = (WorkItem) e.Row.DataItem;

				Label lblId = (Label) e.Row.FindControl("lblId");
				lblId.Text = workItem.Id.ToString();

				Label lblDateOpened = (Label)e.Row.FindControl("lblDateOpened");
				lblDateOpened.Text = string.Format("{0:d} {0:t}", workItem.AddedDate);

				Label lblPriority = (Label)e.Row.FindControl("lblPriority");
				lblPriority.Text = workItem.Priority.ToString();

				Label lblCategory = (Label)e.Row.FindControl("lblCategory");
				lblCategory.Text = workItem.Category.Description.ToString();

				Label lblAssignedTo = (Label)e.Row.FindControl("lblAssignedTo");
				lblAssignedTo.Text = workItem.AssignedTo.DisplayName.ToString();
				
				Label lblStatus = (Label)e.Row.FindControl("lblStatus");
				lblStatus.Text = workItem.Status.Description.ToString();

				Label lblMilestone = (Label)e.Row.FindControl("lblMilestone");
				lblMilestone.Text = workItem.Milestone.Name;
				
				Label lblSummary = (Label)e.Row.FindControl("lblSummary");
				lblSummary.Text = workItem.Summary.ToString();

				string editUrl = EditUrl("Id", workItem.Id.ToString(), "EditWorkItem", "ProjectId=" + workItem.Project.Id.ToString());
				e.Row.Attributes.Add("onclick", string.Format("location.href = '{0}';", editUrl));
				e.Row.Attributes.Add("onmouseover", "this.style.cursor='pointer';");
				e.Row.Attributes.Add("onmouseout", "this.style.cursor='default';");
			}
		}

		private void BindProjects()
		{
			this.ddlProject.DataTextField = "Name";
			this.ddlProject.DataValueField = "Id";
			this.ddlProject.DataSource = this.ProjectRepository.ListVisibleToPerson(this.Person);
			this.ddlProject.DataBind();
			this.ddlProject.Items.Insert(0, new ListItem("Select One", "0"));
			this.ddlProject.SelectedValue = this.UserState.SelectedProjectId.ToString();
		}

		private void BindGrid(Project project)
		{
			if (project != null)
			{
				//DetachedCriteria criteria = DetachedCriteria.For<WorkItem>();
				//criteria.Add(Expression.Eq("Project.Id", project.Id));
				//if (this.chkOpenOnly.Checked)
				//{
				//    criteria.CreateCriteria("Status").Add(Expression.Eq("IsOpen", true));
				//}
				//criteria.AddOrder(Order.Asc(this.gvWorkItems.SortExpression));
				//this.gvWorkItems.DataSource = this.WorkItemRepository.List(criteria);

				var query = this.WorkItemRepository.AsQueryable();
				query.Where(w => w.Project == project);
				if (this.chkOpenOnly.Checked)
				{
					query.Where(w => w.Status.IsOpen == true);
				}
				this.gvWorkItems.DataSource = query.ToArray();
			}
			else
			{
				this.gvWorkItems.DataSource = null;
			}
			this.gvWorkItems.DataBind();
		}

		private void SetupLinks(Project project)
		{
			if ( project != null )
			{
				this.hlAdd.Visible = this.UserCanAddWorkItems(project);
				this.hlAdd.NavigateUrl = EditUrl("ProjectId", project.Id.ToString(), "EditWorkItem");
				this.hlProjectPref.Visible = true;
				this.hlProjectPref.NavigateUrl = EditUrl("ProjectId", project.Id.ToString(), "EditProjectPersonPreferences");
			}
			else
			{
				this.hlAdd.Visible = false;
				this.hlProjectPref.Visible = false;
			}
		}

		private bool UserCanAddWorkItems(Project project)
		{
			ProjectPerson projectPerson = this.ProjectPersonRepository.GetByProjectAndPerson(project, this.Person);
			return projectPerson.Role == Role.Creator || projectPerson.Role == Role.Manager;
		}

		private Project GetSelectedProject()
		{
			int selectedProjectId = int.Parse(this.ddlProject.SelectedValue);
			if ( selectedProjectId != 0 )
			{
				return this.ProjectRepository.Get(selectedProjectId);
			}
			return null;
		}

		private void SaveToUserState(Project project)
		{
			if ( project != null )
			{
				UserState.SelectedProjectId = project.Id;
			}
			else
			{
				UserState.SelectedProjectId = 0;
			}
		}
	}
}